package com.uujava.minibox.ui.tree;

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.ArrayList;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JToolTip;
import javax.swing.JTree;
import javax.swing.ToolTipManager;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

import com.mxcyk.serviceLogic.*;
import com.uujava.minibox.config.Config;
import com.uujava.minibox.ui.tree.*;

public class Tree extends JTree implements MouseListener, MouseMotionListener {

	DefaultMutableTreeNode root;

	Run run = Run.getRun();// 程序执行类
	//Config conf = Config.getConfig();// 得到系统配置
	final String strItemTitleAdd = "添加";
	final String strItemTitleDel = "刪除";
	final String strItemTitleRename = "重命名";
	final String strItemTitlMessagee = "屬性";
	// -------------JtoolIip-----------------------------------------------
	public ShowAppToolTip toolTip= new ShowAppToolTip();

	// -------------JtoolIip-----------------------------------------------
	public Tree(String[] strTitle, String[] strPath) {
		addMouseListener(this);
		ToolTipManager.sharedInstance().registerComponent(this);// 提示注册
		MenuInit();// 初始化菜单
		root = new DefaultMutableTreeNode("root");
		for (int len = strTitle.length, i = 0; i < len; i++) {
			root.add(addGroup(strTitle[i], strPath[i]));
		}

		this.setUI(new TreeUI());// 设置树的平行化
		this.setModel(new DefaultTreeModel(root));
		this.setRootVisible(false);// 隐藏根节点
		this.setToggleClickCount(1);//展开节点之前的鼠标单击数
		
		MyTreeCellRenderer myCellRenderer = new MyTreeCellRenderer();
		// 设置叶子节点的图标
		this.setCellRenderer(myCellRenderer);

		this.addMouseMotionListener(this);
		// --------设置toolTip的背景图片-------------------------------------
		 //toolTip.setPatch(getClass().getResource("/Skins/content_bg2.9.png"), false);
	}

    @Override
    @SuppressWarnings("empty-statement")
	public JToolTip createToolTip() {
		if (toolTip == null) {
			toolTip = new ShowAppToolTip();;

			// toolTip.getButton().addActionListener(toolTipBtnListener);
			toolTip.setComponent(this);

		}

		return toolTip;
	}

	/**
	 * 设置提示出现的位置
	 */
	public Point getToolTipLocation(MouseEvent event) {
		TreePath path = this.getClosestPathForLocation(event.getPoint().x,
				event.getPoint().y);
		Rectangle rect = this.getPathBounds(path);
		if (rect != null) {
			Point point = new Point(rect.x - 250, rect.y);
			return point;
		} else {
			return null;
		}

	}

	/**
	 * 功能：创建一个分组
	 * 
	 * @param strGroupTitle
	 *            分组的标题
	 * @param strPath
	 *            叶子节点的路径
	 * @return 返回分组
	 */
	private DefaultMutableTreeNode addGroup(String strGroupTitle, String strPath) {
		FileList getapp = new FileList(strPath);
		MakeFileLise FileList1 = getapp.getApp();
		ArrayList<Appfile> appfile = FileList1.getLs();
		int length = appfile.size();
		DefaultMutableTreeNode groupNode = new DefaultMutableTreeNode(
				strGroupTitle + " [" + length + "]");// 这个空格不能少
		// groupNode.set

		for (int i = 0; i < length; i++) {
			String name = appfile.get(i).getAppName();
			JLabel lab = new JLabel(appfile.get(i).getAppIcon(), JLabel.LEFT);

			lab.setText(name.substring(0, name.lastIndexOf('.')));// 去除后缀名后的名字
			lab.setName(name);// 设置控件的名字为为监听者准备
			lab.setToolTipText(name);// 显示提示信息
			DefaultMutableTreeNode node = new DefaultMutableTreeNode(lab);
			groupNode.add(node);
		}
		appfile = null;// 释放资源
		return groupNode;
	}

	JPopupMenu popMenu;

	JMenuItem addItem;
	JMenuItem delItem;
	JMenuItem editItem;

	public void MenuInit() {
		PopMenu pop = new PopMenu();
		popMenu = new JPopupMenu();
		addItem = new JMenuItem(strItemTitleAdd);
		addItem.addActionListener(pop);

		delItem = new JMenuItem(strItemTitleDel);
		delItem.addActionListener(pop);
		editItem = new JMenuItem(strItemTitleRename);
		editItem.addActionListener(pop);

		popMenu.add(addItem);
		popMenu.add(delItem);
		popMenu.add(editItem);

	}

	// 用于处理弹出菜单对应的事件.
	class PopMenu implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {

			JMenuItem item = (JMenuItem) e.getSource();
			String strFlag = item.getText();

			TreePath treepath = getSelectionPath();
			// 下面两行取得选取节点的父节点.
			DefaultMutableTreeNode selectionNode = (DefaultMutableTreeNode) treepath
					.getLastPathComponent();
			TreeNode parent = (TreeNode) selectionNode.getParent();

			String strParent = parent.toString();
			strParent = strParent.substring(0, strParent.lastIndexOf(' '));// 提取父节点中的
			// 获得当前应用存放的目录
			StringBuffer strPath = new StringBuffer(Config.DIR).append(
					Config.SEPARATOR).append(strParent).append(
					Config.SEPARATOR);
			strParent = null;

			// -----------------------------------------------------------
			if (strFlag.equals(strItemTitleAdd)) {
				add(strPath);

			} else if (strFlag.equals(strItemTitleDel)) {
				del(strPath);
			} else if (strFlag.equals(strItemTitleRename)) {

			} else if (strFlag.equals(strItemTitlMessagee)) {

			}

		}

		/**
		 * 功能:删除文件 作者:k 2013年7月25日15:39:18
		 * 
		 * @param path
		 *            文件所在目录的路径
		 */
		void del(StringBuffer path) {
			DefaultMutableTreeNode note = (DefaultMutableTreeNode) getLastSelectedPathComponent();

			JLabel jlab = (JLabel) note.getUserObject();
			path.append(jlab.getName());
			jlab = null;
			print("PATH:" + path.toString());
			/**
			 * 此处需要优化代码 吧删除文件的操作放入一个单独的线程中处理.
			 */
			new File(path.toString()).delete();

			// ---------------------------------------------------------
			DefaultMutableTreeNode parent = (DefaultMutableTreeNode) note
					.getParent();
			print(parent.getPath().toString());
			parent.remove(note);
			note = null;
			((DefaultTreeModel) getModel()).reload(parent);
		}

		void add(StringBuffer path) {
			JFileChooser chooser = new JFileChooser();
			int result = chooser.showOpenDialog(null);
			if (result != JFileChooser.APPROVE_OPTION)// 取消了打开文件
				return;
			String strFileName = chooser.getSelectedFile().getName();

			File in = new File(chooser.getSelectedFile().getPath());
			File out = new File(path.append(strFileName).toString());
			try {
				copyFile(in, out, false);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
				JOptionPane.showMessageDialog(null, "文件拷贝出错!", "错误",
						JOptionPane.WARNING_MESSAGE);
			}

		}

		public long copyFile(File srcFile, File destFile, boolean overlay)
				throws FileNotFoundException {
			if (!srcFile.exists()) {
				throw new FileNotFoundException("At path "
						+ srcFile.getAbsolutePath());
			}
			if (destFile.exists() && overlay) {
				destFile.delete();
			}
			// 获取源文件和目标文件的输入输出流
			FileInputStream fin = new FileInputStream(srcFile);
			FileOutputStream fout = new FileOutputStream(destFile);
			// 获取输入输出通道
			FileChannel fcin = fin.getChannel();
			FileChannel fcout = fout.getChannel();
			long totalBytesReaded = 0;
			try {
				totalBytesReaded = fcin.transferTo(0, fcin.size(), fcout);
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					fin.close();
					fout.close();
					fcin.close();
					fcout.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			return totalBytesReaded;
		}

	}

	void print(String str) {
		System.out.println(str);
	}

	public static void main(String[] args) {
		JFrame jf = new JFrame("MiniBox");

		String[] ls3_path = { Config.APPLY + "常用应用", Config.APPLY  + "游戏",
				Config.APPLY+ "桌面" };
		String[] names3 = { "常用应用", "游戏", "桌面" };

		jf.add(new Tree(names3, ls3_path));
		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 设定窗体关闭后自动退出进程
		jf.setSize(200, 500);
		jf.setVisible(true);

	}

	@Override
	public void mouseClicked(MouseEvent arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		// -------------弹出的提示---------------------------------------
		int selRow = getRowForLocation(e.getX(), e.getY()); // 返回节点所在的行，-1表示鼠标定位不在显示的单元边界内
		TreePath selPath = getPathForLocation(e.getX(), e.getY()); // 返回指定节点的树路径

	}

	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		// -------------右键弹出菜单---------------------------------------
		int selRow = getRowForLocation(e.getX(), e.getY()); // 返回节点所在的行，-1表示鼠标定位不在显示的单元边界内
		//TreePath selPath = getPathForLocation(e.getX(), e.getY()); // 返回指定节点的树路径
		boolean condition = true;
		condition = condition && (selRow != -1); // 如果选中
		condition = condition && (e.getClickCount() == 1); // 单击
		// 如果是右键点击
		if (condition == true && (e.getButton() == 3)) {
			popMenu.show(e.getComponent(), e.getX(), e.getY());
			// 选中节点
			TreePath path = getPathForLocation(e.getX(), e.getY());

			setSelectionPath(path);// 设置当前位置的节点为选中节点
		}

		// ----------------------------------------------------

		// 双击
		if (e.getClickCount() == 2) {

			TreePath treepath = getSelectionPath();
			// 下面两行取得选取节点的父节点.
			DefaultMutableTreeNode selectionNode = (DefaultMutableTreeNode) treepath
					.getLastPathComponent();
			TreeNode parent = (TreeNode) selectionNode.getParent();
			if (parent != null) {
				// 由DefaultTreeModel的removeNodeFromParent()方法删除节点，包含它的子节点。
				// treeModel.removeNodeFromParent(selectionNode);
				// 获得父节点的标题parent.toString()
				DefaultMutableTreeNode note = (DefaultMutableTreeNode) getLastSelectedPathComponent();

				if (note.isLeaf()) {// 是否是叶子节点
					JLabel jlab = (JLabel) note.getUserObject();
					String strParent = parent.toString();
					strParent = strParent.substring(0, strParent
							.lastIndexOf(' '));// 提取父节点中的
					File runFile = new File(Config.APPLY
							+ strParent + Config.SEPARATOR + jlab.getName());
					print(runFile.getPath());
					run.run(runFile);
				}
			}

		}

	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mouseDragged(MouseEvent e) {
		// TODO Auto-generated method stub
		// 鼠标按键在组件上按下并拖动时调用。
	}

	@Override
	public void mouseMoved(MouseEvent e) {
		// TODO Auto-generated method stub
		// 鼠标按键在组件上按下并拖动时调用。
		TreePath path = getPathForLocation(e.getX(), e.getY());
		if (path != null) {
			DefaultMutableTreeNode node = (DefaultMutableTreeNode) path
					.getLastPathComponent();
			if (node.isLeaf()) {// 是否为叶子节点
				JLabel jl = (JLabel) node.getUserObject();
				setToolTipText("<html><body>类别:"+"<br/>名称:"+jl.getText()+"</body></html>");
			}
		} else {
			//鼠标移出
		}

	}

}
